using B.S.XZYData.Api.Read.Application.Command.SalesOrder;
using B.S.XZYData.Domain.XZY;
using B.S.XZYData.ErrorCode;
using B.S.XZYData.Infrastructure.Interface;
using MediatR;
using NPOI.SS.UserModel;
using NPOI.XSSF.UserModel;
using SqlSugar;
using System.Linq;
using SalesOrderEntity = B.S.XZYData.Domain.XZY.SalesOrder;

namespace B.S.XZYData.Api.Read.Application.Handler.SalesOrder
{
    /// <summary>
    /// 导出销售订单处理器
    /// </summary>
    public class ExportSalesOrderHandler : IRequestHandler<ExportSalesOrderCommand, ApiResult<byte[]>>
    {
        private readonly IBaseRepository<SalesOrderEntity> _salesOrderRepo;
        private readonly IBaseRepository<SalesOrderProduct> _salesOrderProductRepo;

        public ExportSalesOrderHandler(
            IBaseRepository<SalesOrderEntity> salesOrderRepo,
            IBaseRepository<SalesOrderProduct> salesOrderProductRepo)
        {
            _salesOrderRepo = salesOrderRepo;
            _salesOrderProductRepo = salesOrderProductRepo;
        }

        public async Task<ApiResult<byte[]>> Handle(ExportSalesOrderCommand request, CancellationToken cancellationToken)
        {
            try
            {
                // 查询销售订单数据
                var query = _salesOrderRepo.GetAll().Where(x => !x.IsDeleted);

                // 应用筛选条件
                if (!string.IsNullOrEmpty(request.OrderNo))
                {
                    query = query.Where(x => x.OrderNo.Contains(request.OrderNo));
                }

                if (!string.IsNullOrEmpty(request.Remark))
                {
                    query = query.Where(x => x.Remark != null && x.Remark.Contains(request.Remark));
                }

                // 按创建时间倒序
                query = query.OrderByDescending(x => x.CreateTime);

                var salesOrders = await query.ToListAsync();

                // 创建Excel工作簿
                using var workbook = new XSSFWorkbook();
                
                // 创建销售订单主表工作表
                var mainSheet = workbook.CreateSheet("销售订单主表");
                CreateSalesOrderMainSheet(mainSheet, salesOrders);

                // 如果需要包含产品明细，创建产品明细工作表
                if (request.IncludeProductDetails)
                {
                    var detailSheet = workbook.CreateSheet("销售订单产品明细");
                    await CreateSalesOrderProductDetailSheet(detailSheet, salesOrders);
                }

                // 导出为字节数组
                using var ms = new MemoryStream();
                workbook.Write(ms);
                var excelBytes = ms.ToArray();

                return ApiResult<byte[]>.Success(excelBytes);
            }
            catch (Exception ex)
            {
                return ApiResult<byte[]>.Error($"导出销售订单失败：{ex.Message}");
            }
        }

        /// <summary>
        /// 创建销售订单主表工作表
        /// </summary>
        private void CreateSalesOrderMainSheet(ISheet sheet, List<SalesOrderEntity> salesOrders)
        {
            // 创建标题行样式
            var headerStyle = CreateHeaderStyle(sheet.Workbook);

            // 创建标题行
            var headerRow = sheet.CreateRow(0);
            var headers = new[] { "单据编号", "备注", "创建时间", "创建人", "修改时间", "修改人" };
            
            for (int i = 0; i < headers.Length; i++)
            {
                var cell = headerRow.CreateCell(i);
                cell.SetCellValue(headers[i]);
                cell.CellStyle = headerStyle;
            }

            // 填充数据
            for (int i = 0; i < salesOrders.Count; i++)
            {
                var row = sheet.CreateRow(i + 1);
                var order = salesOrders[i];

                var orderNo = order.OrderNo ?? string.Empty;
                var remark = order.Remark ?? string.Empty;
                var createTimeStr = order.CreateTime == default(DateTime) ? string.Empty : order.CreateTime.ToString("yyyy-MM-dd HH:mm:ss");
                var creatorName = order.CreatorId <= 0 ? string.Empty : string.Empty; // 目前无用户表映射，留空
                var modifyTimeStr = order.ModifyTime.HasValue && order.ModifyTime.Value != default(DateTime)
                    ? order.ModifyTime.Value.ToString("yyyy-MM-dd HH:mm:ss")
                    : string.Empty;
                var modifierName = !order.ModifierId.HasValue || order.ModifierId.Value <= 0 ? string.Empty : string.Empty;

                row.CreateCell(0).SetCellValue(orderNo);
                row.CreateCell(1).SetCellValue(remark);
                row.CreateCell(2).SetCellValue(createTimeStr);
                row.CreateCell(3).SetCellValue(creatorName);
                row.CreateCell(4).SetCellValue(modifyTimeStr);
                row.CreateCell(5).SetCellValue(modifierName);
            }

            // 自动调整列宽
            for (int i = 0; i < headers.Length; i++)
            {
                sheet.AutoSizeColumn(i);
            }
        }

        /// <summary>
        /// 创建销售订单产品明细工作表
        /// </summary>
        private async Task CreateSalesOrderProductDetailSheet(ISheet sheet, List<SalesOrderEntity> salesOrders)
        {
            // 创建标题行样式
            var headerStyle = CreateHeaderStyle(sheet.Workbook);

            // 创建标题行
            var headerRow = sheet.CreateRow(0);
            var headers = new[] { "销售订单编号", "产品编号", "产品名称", "产品规格", "工单编号", "订单数量", "完成数量", "创建时间", "创建人" };
            
            for (int i = 0; i < headers.Length; i++)
            {
                var cell = headerRow.CreateCell(i);
                cell.SetCellValue(headers[i]);
                cell.CellStyle = headerStyle;
            }

            // 查询所有产品明细
            var orderIds = salesOrders.Select(x => x.Id).ToList();
            var productDetails = await _salesOrderProductRepo.GetAll()
                .Where(x => orderIds.Contains(x.SalesOrderId))
                .OrderBy(x => x.SalesOrderId)
                .OrderBy(x => x.CreateTime)
                .ToListAsync();

            // 创建订单编号映射
            var orderNoMapping = salesOrders.ToDictionary(x => x.Id, x => x.OrderNo);

            // 填充数据
            for (int i = 0; i < productDetails.Count; i++)
            {
                var row = sheet.CreateRow(i + 1);
                var detail = productDetails[i];

                var salesOrderNo = orderNoMapping.GetValueOrDefault(detail.SalesOrderId, string.Empty) ?? string.Empty;
                var productCode = detail.ProductCode ?? string.Empty;
                var productName = detail.ProductName ?? string.Empty;
                var productSpec = detail.ProductSpec ?? string.Empty;
                var workOrderNo = detail.WorkOrderNo ?? string.Empty;
                var qty = detail.Quantity;
                var completedQty = detail.CompletedQuantity;
                var createTimeStr = detail.CreateTime == default(DateTime) ? string.Empty : detail.CreateTime.ToString("yyyy-MM-dd HH:mm:ss");
                var creatorName = detail.CreatorId <= 0 ? string.Empty : string.Empty; // 暂无映射

                row.CreateCell(0).SetCellValue(salesOrderNo);
                row.CreateCell(1).SetCellValue(productCode);
                row.CreateCell(2).SetCellValue(productName);
                row.CreateCell(3).SetCellValue(productSpec);
                row.CreateCell(4).SetCellValue(workOrderNo);
                row.CreateCell(5).SetCellValue(qty);
                row.CreateCell(6).SetCellValue(completedQty);
                row.CreateCell(7).SetCellValue(createTimeStr);
                row.CreateCell(8).SetCellValue(creatorName);
            }

            // 自动调整列宽
            for (int i = 0; i < headers.Length; i++)
            {
                sheet.AutoSizeColumn(i);
            }
        }

        /// <summary>
        /// 创建标题行样式
        /// </summary>
        private ICellStyle CreateHeaderStyle(IWorkbook workbook)
        {
            var style = workbook.CreateCellStyle();
            var font = workbook.CreateFont();
            
            font.IsBold = true;
            font.FontHeightInPoints = 12;
            style.SetFont(font);
            
            style.Alignment = HorizontalAlignment.Center;
            style.VerticalAlignment = VerticalAlignment.Center;
            
            // 设置边框
            style.BorderTop = BorderStyle.Thin;
            style.BorderBottom = BorderStyle.Thin;
            style.BorderLeft = BorderStyle.Thin;
            style.BorderRight = BorderStyle.Thin;
            
            return style;
        }
    }
}
